package com.cabal.common.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.*;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.*;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.EntityBuilder;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.LayeredConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.conn.ssl.TrustStrategy;
import org.apache.http.cookie.Cookie;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.HttpMultipartMode;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.*;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.util.Assert;

import javax.net.ssl.*;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InterruptedIOException;
import java.net.URI;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.*;
import java.util.Map.Entry;

/**
 * httpClient工具类
 *
 * @author shenkang
 * @Description:
 * @date 2017年9月15日 下午5:28:38
 */
@Slf4j
public class HttpClientUtil {

    private static final int CONNECT_TIMEOUT = 60000;//请求连接超时,客户端与与服务器建立连接(单位：毫秒)
    private static final int SOCKET_TIMEOUT = 60000;//读取响应超时,连接已建立(单位：毫秒)

    /**
     * 执行GET请求
     *
     * @param url
     * @param param 请求参数
     * @return
     */
    public static String doGet(String url, Map<String, String> param) {

        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            URIBuilder builder = new URIBuilder(url);
            if (param != null) {
                for (String key : param.keySet()) {
                    builder.addParameter(key, param.get(key));
                }
            }
            URI uri = builder.build();

            HttpGet httpGet = new HttpGet(uri);
            //设置超时时间
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
            httpGet.setConfig(requestConfig);

            response = httpclient.execute(httpGet);
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(),
                        "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    /**
     * 执行GET请求
     *
     * @param url
     * @param connectTimeout 连接超时
     * @param socketTimeout  响应超时
     * @return
     */
    public static String doGet(String url, int connectTimeout, int socketTimeout) {

        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            URIBuilder builder = new URIBuilder(url);
            URI uri = builder.build();

            HttpGet httpGet = new HttpGet(uri);
            //设置超时时间
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeout).build();
            httpGet.setConfig(requestConfig);

            response = httpclient.execute(httpGet);
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(),
                        "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    /**
     * 执行Post请求
     *
     * @param url
     * @param headerParams 请求头部参数
     * @param bodyParams   请求体参数
     * @return
     */
    public static String doPost(String url, Map<String, String> headerParams,
                                Map<String, String> bodyParams) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            HttpPost httpPost = new HttpPost(url);
            //设置超时时间
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
            httpPost.setConfig(requestConfig);

            if (headerParams != null) {// 设置请求头
                Set<Entry<String, String>> entrysSet = headerParams
                        .entrySet();
                Iterator<Entry<String, String>> entryItera = entrysSet
                        .iterator();
                while (entryItera.hasNext()) {
                    Entry<String, String> entry = entryItera.next();
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }

            if (bodyParams != null) {
                List<NameValuePair> paramList = new ArrayList<>();
                for (String key : bodyParams.keySet()) {
                    paramList.add(new BasicNameValuePair(key, bodyParams
                            .get(key)));
                }
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(
                        paramList, "utf-8");
                httpPost.setEntity(entity);
            }
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return resultString;
    }

    /**
     * 执行Post请求
     *
     * @param url
     * @param headerParams 请求头部参数
     * @return
     */
    public static String doPost(String url, Map<String, String> headerParams) {
        return doPost(url, headerParams, null);
    }

    /**
     * 执行Post请求(提交json字符串)
     *
     * @param url
     * @param headerParams 请求头部参数
     * @param json         提交的json字符串
     * @return
     */
    public static String doPostJson(String url, Map<String, String> headerParams, String json) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            HttpPost httpPost = new HttpPost(url);
            //设置超时时间
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
            httpPost.setConfig(requestConfig);

            if (headerParams != null) {// 设置请求头
                Set<Entry<String, String>> entrysSet = headerParams
                        .entrySet();
                Iterator<Entry<String, String>> entryItera = entrysSet
                        .iterator();
                while (entryItera.hasNext()) {
                    Entry<String, String> entry = entryItera.next();
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }


    public static String doPostJsonProxy(String url, Map<String, String> headerParams, String
            json, Map<String, String> proxyParams) {
        CloseableHttpResponse response = null;
        String resultString = "";
        CloseableHttpClient httpClient = null;
        try {
            HttpPost httpPost = new HttpPost(url);
            HttpHost proxy = new HttpHost(proxyParams.get("ip"), Integer.parseInt(proxyParams.get("port")), "http");
            // 设置认证
            CredentialsProvider provider = new BasicCredentialsProvider();
            provider.setCredentials(new AuthScope(proxy), new UsernamePasswordCredentials(proxyParams.get("username"), proxyParams.get("password")));
            httpClient = getHttpClientProxy(provider);
            //设置超时时间
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).setProxy(proxy).build();
            httpPost.setConfig(requestConfig);

            if (headerParams != null) {// 设置请求头
                Set<Entry<String, String>> entrysSet = headerParams
                        .entrySet();
                Iterator<Entry<String, String>> entryItera = entrysSet
                        .iterator();
                while (entryItera.hasNext()) {
                    Entry<String, String> entry = entryItera.next();
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            httpPost.addHeader("Content-Type", "application/json;charset=utf-8");
            StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
            httpPost.setEntity(entity);
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    /**
     * 执行Post请求(提交xml字符串)
     *
     * @param url
     * @param headerParams
     * @param xml
     * @return
     */
    public static String doPostXml(String url,
                                   Map<String, String> headerParams, String xml) {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            HttpPost httpPost = new HttpPost(url);
            //设置超时时间
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
            httpPost.setConfig(requestConfig);

            if (headerParams != null) {// 设置请求头
                Set<Entry<String, String>> entrysSet = headerParams
                        .entrySet();
                Iterator<Entry<String, String>> entryItera = entrysSet
                        .iterator();
                while (entryItera.hasNext()) {
                    Entry<String, String> entry = entryItera.next();
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }
            httpPost.addHeader("Content-Type", "application/impl;charset=utf-8");
            StringEntity entity = new StringEntity(xml, ContentType.create("application/xml", Consts.UTF_8));
            httpPost.setEntity(entity);
            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                log.error("" + e);
            }
        }

        return resultString;
    }

    public static String doPostXForm(String url,
                                     Map<String, String> headerParams, Map<String, String> bodyParams) {
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);
            //设置超时时间
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
            httpPost.setConfig(requestConfig);

            if (headerParams != null) {// 设置请求头
                Set<Entry<String, String>> entrysSet = headerParams
                        .entrySet();
                Iterator<Entry<String, String>> entryItera = entrysSet
                        .iterator();
                while (entryItera.hasNext()) {
                    Entry<String, String> entry = entryItera.next();
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }

            EntityBuilder builder = EntityBuilder.create();
            List<NameValuePair> nameValPairList = new ArrayList<NameValuePair>();
            if (bodyParams != null) {// 设置body参数

                for (String key : bodyParams.keySet()) {
                    NameValuePair nameValuePair = new BasicNameValuePair(key,
                            bodyParams.get(key));
                    nameValPairList.add(nameValuePair);
                }
            }
            builder.setParameters(nameValPairList);
            builder.setContentEncoding("UTF-8");
            httpPost.addHeader("Content-Type",
                    "application/x-www-form-urlencoded;charset=utf-8");

//			HttpEntity entity = builder.build();
            HttpEntity entity = new UrlEncodedFormEntity(nameValPairList, "UTF-8");
            httpPost.setEntity(entity);

            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
        } catch (Exception e) {
            log.error("HttpClientUtil Exception:" + e);
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                log.error("HttpClientUtil IOException:" + e);
            }
        }
        return resultString;
    }

    public static String doPostXFormSSL(String url,
                                        Map<String, String> headerParams, Map<String, String> bodyParams, Map<String, String> outCookies) {
        String body = "";
        String encoding = "utf-8";
        CloseableHttpClient client = null;
        CookieStore cookieStore = new BasicCookieStore();
        HttpClientContext localContext = HttpClientContext.create();
        localContext.setCookieStore(cookieStore);
        try {
            client = createClient();
            // 创建post方式请求对象
            HttpPost httpPost = new HttpPost(url);
            if (headerParams != null) {
                if (headerParams.get("Accept") != null)
                    httpPost.setHeader("Accept", headerParams.get("Accept"));
                if (headerParams.get("Cookie") != null)
                    httpPost.setHeader("Cookie", headerParams.get("Cookie"));
                if (headerParams.get("Accept-Encoding") != null)
                    httpPost.setHeader("Accept-Encoding", headerParams.get("Accept-Encoding"));
                if (headerParams.get("Accept-Language") != null)
                    httpPost.setHeader("Accept-Language", headerParams.get("Accept-Language"));
                if (headerParams.get("Host") != null) httpPost.setHeader("Host", headerParams.get("Host"));
                if (headerParams.get("User-Agent") != null)
                    httpPost.setHeader("User-Agent", headerParams.get("User-Agent"));
                if (headerParams.get("x-requested-with") != null)
                    httpPost.setHeader("x-requested-with", headerParams.get("x-requested-with"));
                if (headerParams.get("Encoding") != null) encoding = headerParams.get("Encoding");
//                if(headerParams.get("Content-Type")!=null) contentType =headerParams.get("Content-Type");

                // 设置请求头
                Set<Entry<String, String>> entrysSet = headerParams.entrySet();
                Iterator<Entry<String, String>> entryItera = entrysSet.iterator();
                while (entryItera.hasNext()) {
                    Entry<String, String> entry = entryItera.next();
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }

            if (bodyParams != null) {
                // 装填参数
                List<NameValuePair> nvps = new ArrayList<NameValuePair>();
                if (bodyParams != null) {
                    for (Entry<String, String> entry : bodyParams.entrySet()) {
                        nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                    }
                }
                httpPost.setEntity(new UrlEncodedFormEntity(nvps, encoding));
            }

            EntityBuilder builder = EntityBuilder.create();
            builder.setContentEncoding("UTF-8");
            httpPost.addHeader("Content-Type",
                    "application/x-www-form-urlencoded;charset=utf-8");


            System.out.println("请求地址：" + url);
            // 执行请求操作，并拿到结果（同步阻塞）
            CloseableHttpResponse response = client.execute(httpPost, localContext);
            // 获取结果实体
            try {
                // 如果需要输出cookie
                if (outCookies != null) {
                    List<Cookie> cookies = cookieStore.getCookies();
                    for (int i = 0; i < cookies.size(); i++) {
                        outCookies.put(cookies.get(i).getName(), cookies.get(i).getValue());
                    }
                }
                HttpEntity entity = response.getEntity();
                System.out.println("返回：" + response.getStatusLine());
                if (entity != null) {
                    // 按指定编码转换结果实体为String类型
                    body = EntityUtils.toString(entity, encoding);
                    // System.out.println("返回："+body);
                }
            } finally {
                response.close();
            }
        } catch (Exception e) {
            log.error("" + e);
        } finally {
            try {
                client.close();
            } catch (IOException e) {
                log.error("" + e);
            }
        }

        return body;
    }

    //提交表单，key=value&key=value字符串方式
    public static String doPostXFormStr(String url, Map<String, Object> bodyParams) {
        StringBuffer sb = new StringBuffer();
        Iterator<Entry<String, Object>> bodyParItera = bodyParams.entrySet().iterator();
        int i = 0;
        while (bodyParItera.hasNext()) {
            Entry<String, Object> bodyParEntry = bodyParItera.next();
            String key = bodyParEntry.getKey();
            Object value = bodyParEntry.getValue();
            if (i > 0) {
                sb.append("&").append(key).append("=").append(value);
            } else {
                sb.append(key).append("=").append(value);
            }
            i++;
        }
        try {
            HttpPost httpPost = new HttpPost(url);
            //设置超时时间
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
            httpPost.setConfig(requestConfig);

            StringEntity stringEntity = new StringEntity(sb.toString());// param参数，可以为"key1=value1&key2=value2"的一串字符串
            stringEntity.setContentType("application/x-www-form-urlencoded");
            stringEntity.setContentEncoding("UTF-8");
            httpPost.setEntity(stringEntity);
            HttpClient client = new DefaultHttpClient();
            HttpResponse httpResponse = client.execute(httpPost);
            String result = EntityUtils.toString(httpResponse.getEntity(),
                    HTTP.UTF_8);
            return result;
        } catch (IOException e) {
            log.error("" + e);
            return null;
        }
    }


    /**
     * 执行Post请求(上传文件),单个文件
     *
     * @param url
     * @param headerParams
     * @param bodyParams
     * @param multipartPar
     * @return
     */
    public static String doPostMultipart(String url,
                                         Map<String, String> headerParams, Map<String, String> bodyParams,
                                         MultipartPar multipartPar) {
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            File file = new File(multipartPar.getFilePath());
            Assert.isTrue(file.isFile(), "该文件不是文件");

            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);
            //设置超时时间
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
            httpPost.setConfig(requestConfig);

            if (headerParams != null) {// 设置请求头
                Set<Entry<String, String>> entrysSet = headerParams
                        .entrySet();
                Iterator<Entry<String, String>> entryItera = entrysSet
                        .iterator();
                while (entryItera.hasNext()) {
                    Entry<String, String> entry = entryItera.next();
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }

            // 设置上传文件
            // InputStream inputStream = new FileInputStream(zipFileName);
            // File file = new File(imageFileName);
            // String message = "This is a multipart post";

            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
            builder.addBinaryBody(multipartPar.getName(), file,
                    ContentType.DEFAULT_BINARY, multipartPar.getFilePath());
//			builder.setCharset(Charset.forName(HTTP.UTF_8));//设置请求的编码格式 

            // builder.addBinaryBody
            // ("upstream", inputStream, ContentType.create("application/zip"),
            // zipFileName);
            // builder.addTextBody("text", message, ContentType.TEXT_PLAIN);
            //

            if (bodyParams != null) {// 设置body参数
                for (String key : bodyParams.keySet()) {
                    builder.addTextBody(key, bodyParams.get(key), ContentType.create("text/plain", Charset.forName("UTF-8")));
                }
            }

            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);

            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            log.error("HttpClientUtil Exception:" + e);
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                log.error("HttpClientUtil IOException:" + e);
            }
        }
        return resultString;
    }

    /**
     * 执行Post请求(上传文件)，多个文件上传
     *
     * @param url
     * @param headerParams
     * @param bodyParams
     * @param multipartPar
     * @return
     */
    public static String doPostMultipartMulFiles(String url,
                                                 Map<String, String> headerParams, Map<String, String> bodyParams,
                                                 MultipartPar multipartPar) {
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
//			builder.setCharset(Charset.forName(HTTP.UTF_8));//设置请求的编码格式 
            List<MultipartPar> multipartParList = multipartPar.getFilePathList();

            for (MultipartPar multipartParTmp : multipartParList) {
                File file = new File(multipartParTmp.getFilePath());
                Assert.isTrue(file.isFile(), "该文件不是文件");

                builder.addBinaryBody(multipartParTmp.getName(), file,
                        ContentType.DEFAULT_BINARY, multipartParTmp.getFilePath());
            }

            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpPost httpPost = new HttpPost(url);
            //设置超时时间
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
            httpPost.setConfig(requestConfig);

            if (headerParams != null) {// 设置请求头
                Set<Entry<String, String>> entrysSet = headerParams
                        .entrySet();
                Iterator<Entry<String, String>> entryItera = entrysSet
                        .iterator();
                while (entryItera.hasNext()) {
                    Entry<String, String> entry = entryItera.next();
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }

            // 设置上传文件
            // InputStream inputStream = new FileInputStream(zipFileName);
            // File file = new File(imageFileName);
            // String message = "This is a multipart post";

            // builder.addBinaryBody
            // ("upstream", inputStream, ContentType.create("application/zip"),
            // zipFileName);
            // builder.addTextBody("text", message, ContentType.TEXT_PLAIN);
            //

            if (bodyParams != null) {// 设置body参数
                for (String key : bodyParams.keySet()) {
                    builder.addTextBody(key, bodyParams.get(key), ContentType.create("text/plain", Charset.forName("UTF-8")));
                }
            }

            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);

            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            log.error("HttpClientUtil Exception:" + e);
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                log.error("HttpClientUtil IOException:" + e);
            }
        }

        return resultString;
    }

    public static String doPostMultipartMulFilesSSL(String url,
                                                    Map<String, String> headerParams, Map<String, String> bodyParams,
                                                    MultipartPar multipartPar) {
        CloseableHttpResponse response = null;
        String resultString = "";
        try {
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
//			builder.setCharset(Charset.forName(HTTP.UTF_8));//设置请求的编码格式 
            List<MultipartPar> multipartParList = multipartPar.getFilePathList();

            for (MultipartPar multipartParTmp : multipartParList) {
                File file = new File(multipartParTmp.getFilePath());
                Assert.isTrue(file.isFile(), "该文件不是文件");

                builder.addBinaryBody(multipartParTmp.getName(), file,
                        ContentType.DEFAULT_BINARY, multipartParTmp.getFilePath());
            }

            CloseableHttpClient httpClient = createClient();
            HttpPost httpPost = new HttpPost(url);

            if (headerParams != null) {// 设置请求头
                Set<Entry<String, String>> entrysSet = headerParams
                        .entrySet();
                Iterator<Entry<String, String>> entryItera = entrysSet
                        .iterator();

                while (entryItera.hasNext()) {
                    Entry<String, String> entry = entryItera.next();
                    httpPost.addHeader(entry.getKey(), entry.getValue());
                }
            }

            if (bodyParams != null) {// 设置body参数
                for (String key : bodyParams.keySet()) {
                    builder.addTextBody(key, bodyParams.get(key), ContentType.create("text/plain", Charset.forName("UTF-8")));
                }
            }

            HttpEntity entity = builder.build();
            httpPost.setEntity(entity);

            response = httpClient.execute(httpPost);
            resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        } catch (Exception e) {
            log.error("HttpClientUtil Exception:" + e);
        } finally {
            try {
                response.close();
            } catch (IOException e) {
                log.error("HttpClientUtil IOException:" + e);
            }
        }

        return resultString;
    }

    /**
     * 文件上传
     *
     * @author BertWei
     * @Description:
     * @date 2017年12月4日 下午6:06:37
     */
    public static class MultipartPar {

        private String name;// 上传文件
        private String filePath;// 上传源文件路劲
        private List<MultipartPar> filePathList;// 上传源文件路劲

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getFilePath() {
            return filePath;
        }

        public void setFilePath(String filePath) {
            this.filePath = filePath;
        }

        public List<MultipartPar> getFilePathList() {
            return filePathList;
        }

        public void setFilePathList(List<MultipartPar> filePathList) {
            this.filePathList = filePathList;
        }
    }


    private static int SocketTimeout = 30000;// 30秒
    private static int ConnectTimeout = 30000;// 30秒
    private static Boolean SetTimeOut = true;

    private static CloseableHttpClient getHttpClient() {
        RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder
                .create();
        ConnectionSocketFactory plainSF = new PlainConnectionSocketFactory();
        registryBuilder.register("http", plainSF);
        // 指定信任密钥存储对象和连接套接字工厂
        try {
            KeyStore trustStore = KeyStore.getInstance(KeyStore
                    .getDefaultType());
            // 信任任何链接
            TrustStrategy anyTrustStrategy = new TrustStrategy() {
                @Override
                public boolean isTrusted(X509Certificate[] x509Certificates,
                                         String s) throws CertificateException {
                    return true;
                }
            };
            SSLContext sslContext = SSLContexts.custom().useTLS()
                    .loadTrustMaterial(trustStore, anyTrustStrategy).build();
            LayeredConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(
                    sslContext,
                    SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
            registryBuilder.register("https", sslSF);
        } catch (KeyStoreException e) {
            throw new RuntimeException(e);
        } catch (KeyManagementException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        Registry<ConnectionSocketFactory> registry = registryBuilder.build();
        // 设置连接管理器
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(
                registry);
        // connManager.setDefaultConnectionConfig(connConfig);
        // connManager.setDefaultSocketConfig(socketConfig);
        // 构建客户端
        return HttpClientBuilder.create().setConnectionManager(connManager)
                .build();
    }


    private static CloseableHttpClient getHttpClientProxy(CredentialsProvider provider) {
        RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder
                .create();
        ConnectionSocketFactory plainSF = new PlainConnectionSocketFactory();
        registryBuilder.register("http", plainSF);
        // 指定信任密钥存储对象和连接套接字工厂
        try {
            SSLContext sslcontext = createIgnoreVerifySSL();
            registryBuilder.register("https", new SSLConnectionSocketFactory(sslcontext, new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"}, null, SSLConnectionSocketFactory.getDefaultHostnameVerifier()));
        } catch (KeyManagementException e) {
            throw new RuntimeException(e);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
        Registry<ConnectionSocketFactory> registry = registryBuilder.build();
        // 设置连接管理器
        PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(
                registry);
        // connManager.setDefaultConnectionConfig(connConfig);
        // connManager.setDefaultSocketConfig(socketConfig);
        // 构建客户端
        return HttpClientBuilder.create().setConnectionManager(connManager).setDefaultCredentialsProvider(provider)
                .build();
    }

    public static SSLContext createIgnoreVerifySSL() throws NoSuchAlgorithmException, KeyManagementException {
        //SSLContext sc = SSLContext.getInstance("SSLv3");
        SSLContext sc = null;
        InputStream stream = null;
        try {
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("cer/mystore.keystore");
            keyStore.load(stream, "123456".toCharArray());
            sc = SSLContexts.custom().loadKeyMaterial(keyStore, "123456".toCharArray())
                    .build();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        // 实现一个X509TrustManager接口，用于绕过验证，不用修改里面的方法
        X509TrustManager trustManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(
                    X509Certificate[] paramArrayOfX509Certificate,
                    String paramString) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(
                    X509Certificate[] paramArrayOfX509Certificate,
                    String paramString) throws CertificateException {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        sc.init(null, new TrustManager[]{trustManager}, null);
        return sc;
    }


    /**
     * get
     *
     * @param url     请求的url
     * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
     * @return
     * @throws IOException
     */
    public static String get(String url, Map<String, String> queries, String codeFormat)
            throws IOException {
        String responseBody = "";
        // CloseableHttpClient httpClient=HttpClients.createDefault();
        // 支持https
        CloseableHttpClient httpClient = getHttpClient();

        StringBuilder sb = new StringBuilder(url);

        if (queries != null && queries.keySet().size() > 0) {
            boolean firstFlag = true;
            Iterator iterator = queries.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry entry = (Entry<String, String>) iterator.next();
                if (firstFlag) {
                    sb.append("?" + entry.getKey() + "="
                            + entry.getValue());
                    firstFlag = false;
                } else {
                    sb.append("&" + entry.getKey() + "="
                            + entry.getValue());
                }
            }
        }

        HttpGet httpGet = new HttpGet(sb.toString());
        if (SetTimeOut) {
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(SocketTimeout)
                    .setConnectTimeout(ConnectTimeout).build();// 设置请求和传输超时时间
            httpGet.setConfig(requestConfig);
        }
        try {
//			System.out.println("Executing request " + httpGet.getRequestLine());
            // 请求数据
            CloseableHttpResponse response = httpClient.execute(httpGet);
            System.out.println(response.getStatusLine());
            int status = response.getStatusLine().getStatusCode();
            if (status == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                // do something useful with the response body
                // and ensure it is fully consumed
                responseBody = EntityUtils.toString(entity, codeFormat);
                // EntityUtils.consume(entity);
            } else {
                System.out.println("http return status error:" + status);
                throw new ClientProtocolException(
                        "Unexpected response status: " + status);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            httpClient.close();
        }
        return responseBody;
    }


    /**
     * get
     *
     * @param url     请求的url
     * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
     * @return
     * @throws IOException
     */
    public static String get(String url, Map<String, String> queries)
            throws IOException {
        String responseBody = "";
        // CloseableHttpClient httpClient=HttpClients.createDefault();
        // 支持https
        CloseableHttpClient httpClient = getHttpClient();

        StringBuilder sb = new StringBuilder(url);

        if (queries != null && queries.keySet().size() > 0) {
            boolean firstFlag = true;
            Iterator iterator = queries.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry entry = (Entry<String, String>) iterator.next();
                if (firstFlag) {
                    sb.append("?" + entry.getKey() + "="
                            + entry.getValue());
                    firstFlag = false;
                } else {
                    sb.append("&" + entry.getKey() + "="
                            + entry.getValue());
                }
            }
        }

        HttpGet httpGet = new HttpGet(sb.toString());
        if (SetTimeOut) {
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(SocketTimeout)
                    .setConnectTimeout(ConnectTimeout).build();// 设置请求和传输超时时间
            httpGet.setConfig(requestConfig);
        }
        try {
            System.out.println("Executing request " + httpGet.getRequestLine());
            // 请求数据
            CloseableHttpResponse response = httpClient.execute(httpGet);
            System.out.println(response.getStatusLine());
            int status = response.getStatusLine().getStatusCode();
            if (status == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                // do something useful with the response body
                // and ensure it is fully consumed
                responseBody = EntityUtils.toString(entity);
                // EntityUtils.consume(entity);
            } else {
                System.out.println("http return status error:" + status);
                throw new ClientProtocolException(
                        "Unexpected response status: " + status);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            httpClient.close();
        }
        return responseBody;
    }

    /**
     * post
     *
     * @param url     请求的url
     * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
     * @param params  post form 提交的参数
     * @return
     * @throws IOException
     */
    public static String post(String url, Map<String, String> queries,
                              Map<String, String> params) throws IOException {
        String responseBody = "";
        // CloseableHttpClient httpClient = HttpClients.createDefault();
        // 支持https
        CloseableHttpClient httpClient = getHttpClient();

        StringBuilder sb = new StringBuilder(url);

        if (queries != null && queries.keySet().size() > 0) {
            boolean firstFlag = true;
            Iterator iterator = queries.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry entry = (Entry<String, String>) iterator.next();
                if (firstFlag) {
                    sb.append("?" + entry.getKey() + "="
                            + entry.getValue());
                    firstFlag = false;
                } else {
                    sb.append("&" + entry.getKey() + "="
                            + entry.getValue());
                }
            }
        }

        // 指定url,和http方式
        HttpPost httpPost = new HttpPost(sb.toString());
        if (SetTimeOut) {
            RequestConfig requestConfig = RequestConfig.custom()
                    .setSocketTimeout(SocketTimeout)
                    .setConnectTimeout(ConnectTimeout).build();// 设置请求和传输超时时间
            httpPost.setConfig(requestConfig);
        }
        // 添加参数
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        if (params != null && params.keySet().size() > 0) {
            Iterator<Entry<String, String>> iterator = params.entrySet()
                    .iterator();
            while (iterator.hasNext()) {
                Entry<String, String> entry = iterator
                        .next();
                nvps.add(new BasicNameValuePair(entry.getKey(),
                        entry.getValue()));
            }
        }
        httpPost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));
        // 请求数据
        CloseableHttpResponse response = httpClient.execute(httpPost);
        try {
            System.out.println(response.getStatusLine());
            if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                HttpEntity entity = response.getEntity();
                // do something useful with the response body
                // and ensure it is fully consumed
                responseBody = EntityUtils.toString(entity);
                // EntityUtils.consume(entity);
            } else {
                System.out.println("http return status error:"
                        + response.getStatusLine().getStatusCode());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            response.close();
        }
        return responseBody;
    }

    /**
     * 执行GET请求
     *
     * @param url
     * @param headerParams
     * @return
     */
    public static String doGetJson(String url, Map<String, String> headerParams) {
        CloseableHttpClient httpclient = HttpClients.createDefault();

        String resultString = "";
        CloseableHttpResponse response = null;
        try {
            HttpGet httpGet = new HttpGet(url);
            if (headerParams != null) {// 设置请求头
                Set<Entry<String, String>> entrysSet = headerParams
                        .entrySet();
                Iterator<Entry<String, String>> entryItera = entrysSet
                        .iterator();
                while (entryItera.hasNext()) {
                    Entry<String, String> entry = entryItera.next();
                    httpGet.addHeader(entry.getKey(), entry.getValue());
                }
            }

            //设置超时时间
            RequestConfig requestConfig = RequestConfig.custom()
                    .setConnectTimeout(CONNECT_TIMEOUT).setSocketTimeout(SOCKET_TIMEOUT).build();
            httpGet.setConfig(requestConfig);

            response = httpclient.execute(httpGet);
            if (response.getStatusLine().getStatusCode() == 200) {
                resultString = EntityUtils.toString(response.getEntity(),
                        "UTF-8");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (response != null) {
                    response.close();
                }
                httpclient.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return resultString;
    }

    public static void main(String[] arg0) {
        Map<String, String> bodyParams = new HashMap<String, String>();
        bodyParams.put("skus", "7350071076262,34");
        String str =
//	 doPostXForm("http://productStorage.astraea.com.au/cims/commodity/findExitsSkuList",
//	 null, bodyParams);
//	 doPostXForm("http://www.phecda.com/api/Pro/GetExchangeSingle",
//	 null, bodyParams);
                doPost("http://www.phecda861.com/api/Pro/GetExchangeSingle", null);
//	 doPost("http://www.aabbccddeeff.com",null);
        System.out.println("str-->" + str);
    }


    public static CloseableHttpClient createClient() throws Exception {
        TrustStrategy trustStrategy = new TrustStrategy() {
            @Override
            public boolean isTrusted(X509Certificate[] xc, String msg)
                    throws CertificateException {
                return true;
            }
        };
        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(trustStrategy);
        HostnameVerifier hostnameVerifierAllowAll = new HostnameVerifier() {
            @Override
            public boolean verify(String name, SSLSession session) {
                return true;
            }
        };
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                builder.build(), new String[]{"SSLv2Hello", "SSLv3", "TLSv1",
                "TLSv1.1", "TLSv1.2"}, null, hostnameVerifierAllowAll);

        HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {

            @Override
            public boolean retryRequest(IOException exception,
                                        int executionCount, HttpContext context) {

                //重试设置
                if (executionCount >= 5) {
                    // Do not retry if over max retry count
                    return false;
                }
                if (exception instanceof InterruptedIOException) {
                    // Timeout
                    return false;
                }
                if (exception instanceof UnknownHostException) {
                    // Unknown host
                    return false;
                }
                if (exception instanceof ConnectTimeoutException) {
                    // Connection refused
                    return false;
                }
                if (exception instanceof SSLException) {
                    // SSL handshake exception
                    return false;
                }
                HttpClientContext clientContext = HttpClientContext.adapt(context);
                HttpRequest request = clientContext.getRequest();
                boolean idempotent = !(request instanceof HttpEntityEnclosingRequest);
                return idempotent;

            }
        };

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(CONNECT_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT)//超时设置
                .build();
        CloseableHttpClient httpclient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .setRetryHandler(myRetryHandler)//重试设置
                .setDefaultRequestConfig(requestConfig)
                .build();
        return httpclient;
    }

    public static String getClientIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }

        return ip;
    }

}
